﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using System.Net;
using System.IO;

namespace NerdDinner.Models
{
    // Please look details of Location API on http://ipinfodb.com/ip_location_api.php
    public class GeoCoordinates
    {
        public readonly float Latitude;
        public readonly float Longtitude;
        public GeoCoordinates(float latitude, float longtitude)
        {
            Latitude = latitude;
            Longtitude = longtitude;
        }
    }

    public class GeoDataArguments
    {

        public readonly string IP;
        public readonly string CountryCode;
        public readonly string CountryName;
        public readonly string RegionCode;
        public readonly string RegionName;
        public readonly string City;
        public readonly string ZipPostalCode;
        public readonly GeoCoordinates Coordinates;
        public readonly int TimeZone;
        public readonly int GmtOffset;
        public readonly int DstOffset;

        public GeoDataArguments(XContainer source)
        {
            XElement data = source.Element("Ip");
            if (data != null)
                IP = (string)data;
            data = source.Element("City");
            if (data != null)
                City = (string)data;
            data = source.Element("CountryCode");
            if (data != null)
                CountryCode = (string)data;
            data = source.Element("CountryName");
            if (data != null)
                CountryName = (string)data;
            data = source.Element("RegionCode");
            if (data != null)
                RegionCode = (string)data;
            data = source.Element("RegionName");
            if (data != null)
                RegionName = (string)data;
            data = source.Element("ZipPostalCode");
            if (data != null)
                ZipPostalCode = (string)data;
            data = source.Element("TimeZone");
            if (data != null)
                TimeZone = int.Parse((string)data);
            data = source.Element("GmtOffset");
            if (data != null)
                GmtOffset = int.Parse((string)data);
            data = source.Element("DstOffset");
            if (data != null)
                DstOffset = int.Parse((string)data);
            data = source.Element("Latitude");
            XElement data2 = source.Element("Longitude");
            if ((data != null) && (data2 != null))
                Coordinates = new GeoCoordinates((float)data, (float)data2);
        }

    }

    public class Ip2Geo
    {
        //public event GeoDataReceivedEventHandler OnDataReceived;
        //public delegate void GeoDataReceivedEventHandler(object sender, GeoDataArguments e);

        protected const string WebServiceUrlTemplate = "http://ipinfodb.com/ip_query.php";

        //protected static string WebServiceUrl
        //{
        //    get
        //    {
        //        string clientIp = HttpContext.Current.Request.UserHostAddress;
        //        return string.Format(WebServiceUrlTemplate, clientIp);
        //    }
        //}

        protected static string QueryData()
        {
            string result = string.Empty;
            var httpRequest = WebRequest.Create(WebServiceUrlTemplate) as HttpWebRequest;
            if (httpRequest != null)
            {
                var response = httpRequest.GetResponse() as HttpWebResponse;
                if (response != null)
                    using (var reader = new StreamReader(response.GetResponseStream()))
                        result = reader.ReadToEnd();
            }
            return result;
        }

        protected static GeoDataArguments ParseDataToArguments(string response)
        {
            var stringReader = new StringReader(response);
            XElement element = XElement.Load(stringReader);
            var status = (string)element.Element("Status");
            if (string.Compare(status, "ok", true) != 0)
            {
                return null;
            }
            return new GeoDataArguments(element);
        }

        public static GeoCoordinates GetCoordinates()
        {
            string data = QueryData();
            return ParseDataToArguments(data).Coordinates;
        }

        //protected override void OnLoad(EventArgs e)
        //{
        //    if (!Page.IsPostBack)
        //    {
        //        if (OnDataReceived != null)
        //        {
        //            string data = QueryData();
        //            GeoDataArguments args = ParseDataToArguments(data);
        //            OnDataReceived(this, args);
        //        }
        //    }
        //    base.OnLoad(e);
        //}
    }
}